/*
  封装axios函数
  功能：
    1. 复用请求地址：公共请求地址不要重复定义了
    2. 自动携带公共的请求参数
    3. 函数调用返回的promise对象：
      如果是成功状态：请求成功和功能成功
      如果是失败状态：请求失败或功能失败
    4. promise对象内部的结果值
      如果是成功状态：直接得到data数据
      如果是失败状态：直接得到失败原因
    5. 进度提示
*/
import axios from "axios";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

// axios.create方法的返回值，简单理解axios的实例，功能和axios基本一致
const request = axios.create({
  // 请求基础路径，所有通过request发送请求，请求地址前面都会自动加上baseURL
  baseURL: "/mock",
  // 请求的超时时间，超过时间请求会自动中断，请求失败
  timeout: 20000,
  // 公共请求头(固定写死)
  // headers: {},
});

/*
  请求拦截器: 在发送请求之前触发的函数
  响应拦截器：在响应回来的时候触发的函数

  触发流程：
   request({ method: 'xx', url: 'xxx' })
    .then()
    .catch()

    请求拦截器的回调
      一般只会触发成功的回调
    发送请求
    响应拦截器的回调
      看响应状态码
        2xx触发成功的回调函数
        非2xx触发失败的回调函数
    then/catch/的回调 / async await
*/
// 请求拦截器
request.interceptors.request.use(
  // 成功的回调函数
  (config) => {
    // config请求的配置对象
    NProgress.start();
    // 给config添加公共参数（动态的）
    // config.headers.token = "xxxx";

    // 必须返回config对象
    // 返回的config对象，就会在下一步发送请求用上
    return config;
  }
  // 失败的回调函数
  // () => {}
);
// 响应拦截器
request.interceptors.response.use(
  // 成功的回调函数
  (response) => {
    // 请求成功 2xx
    NProgress.done();
    // 功能可能是失败
    if (response.data.code === 200) {
      // 功能成功
      return response.data.data;
    } else {
      // 功能失败
      return Promise.reject(response.data.message || "未知错误，请联系网管");
    }
  },
  // 失败的回调函数
  (error) => {
    NProgress.done();
    console.dir(error);
    // 请求失败
    return Promise.reject(error.message);
  }
);

export default request;
